#include <hd_oled.h>
#include <pd_gpio.h>
#include <hd_led.h>
#include <pd_spi_io.h>
#include <pd_spi_hd.h>
#include <hd_lcd.h>
#include <delay.h>
#include <sd_encode.h>
#include <hd_oled_protocol_i2c.h>
#include <hd_lcd_old.h>
#include <pd_i2c_hd.h>
#include "main.h"


#define OLED_I2C            1   // Select a protocol in I2C or SPI
#define OLED_I2C_HARDWARE   1   // Select hardware or software simulate
struct OLED oled;

extern void SystemClock_Config(void);

int main(void) {
    SystemClock_Config();

    NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);

#ifdef OLED_SPI
    struct GPIO sckGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_5);  // Clock, SPIx_SCK
    struct GPIO sdaGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_7);  // MOSI,  SPIx_MOSI
    struct GPIO resGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_3);  // Reset, General IO, the chip reset pin is better
    struct GPIO dcGPIO  = GPIO.new(GPIOA, LL_GPIO_PIN_1);  // Data or Command, General IO
    struct GPIO csGPIO  = GPIO.new(GPIOA, LL_GPIO_PIN_2);  // Chip Select(Slave Select), General IO
    struct SPIGPIO spiGPIO = SPIGPIO.new(&csGPIO, 1, &sckGPIO, &sdaGPIO, NULL);

#ifdef OLED_SPI_SIMULATE
    struct SPI *spi = (struct SPI *) SPISimulate.new(&spiGPIO);
    spi->init(spi);
#elif OLED_SPI_HARDWARE
    struct SPI *spi = (struct SPI *) SPIHardware.new(SPI1, &spiGPIO);
    spi->init(spi);
#endif
    struct OLEDProtocolSPI *oledProtocolObj = OLEDProtocolSPI.new(spi, &resGPIO, &dcGPIO, &csGPIO);

#elif OLED_I2C
    struct GPIO sckGPIO = GPIO.new(GPIOB, LL_GPIO_PIN_10);  // I2Cx_SCL
    struct GPIO sdaGPIO = GPIO.new(GPIOB, LL_GPIO_PIN_11);  // I2Cx_SDA
#ifdef OLED_I2C_SIMULATE
    struct I2CSimulate i2CObj = I2CSimulate.new(&sckGPIO, &sdaGPIO);
#elif OLED_I2C_HARDWARE
    struct I2CHardware i2CObj = I2CHardware.new(I2C2, &sckGPIO, &sdaGPIO);
#endif
    struct I2C *i2c = (struct I2C *) &i2CObj;
    i2c->init(i2c);
    struct OLEDProtocolI2C *oledProtocolObj = OLEDProtocolI2C.new(i2c);
#endif

    oled = OLED.new(OLED_SIZE_16, OLED_MODE_POSITIVE, (struct OLEDProtocol *) oledProtocolObj);
    oled.init(&oled);

    oled.clear(&oled);
    oled.refresh(&oled);

    // SPI hardware init
    struct GPIO sselGPIO[] = {GPIO.new(GPIOC, LL_GPIO_PIN_4)};
    struct GPIO sclkGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_5);
    struct GPIO misoGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_6);
    struct GPIO mosiGPIO = GPIO.new(GPIOA, LL_GPIO_PIN_7);
    struct SPIGPIO spiGPIO = SPIGPIO.new(sselGPIO, 1, &sclkGPIO, &mosiGPIO, &misoGPIO);
    struct SPI *spi = (struct SPI *) SPIHardware.new(SPI1, &spiGPIO);
    spi->init(spi);

    // LCD初始化
    HD_LCD_Init();

    HD_LCD_ShowChar(0, 0, ':');
    HD_LCD_ShowString(48, 0, (uint8_t *) "TFT LCD");

    uint64_t unicode = utf8_2_unicode((uint8_t *) "ʼ");
    HD_LCD_SetFontColor(RED);
    HD_LCD_ShowUnsignedNum(0, 16, unicode, 10);
    HD_LCD_SetFontColor(GREEN);
    HD_LCD_ShowSignedNum(88, 16, 123, 4);
    HD_LCD_SetFontColor(BLUE);
    HD_LCD_ShowSignedNum(128, 16, -123, 4);

    HD_LCD_SetFontColor(BRRED);
    HD_LCD_ShowHexNum(0, 32, unicode, 10);
    HD_LCD_SetFontColor(LIGHTBLUE);
    HD_LCD_ShowBinNum(0, 48, unicode, 20);

    HD_LCD_SetFontColor(BLACK);
    HD_LCD_SetFontBgColor(RED);
    float t = 0;
    while (1) {
         HD_LCD_ShowFloatNum(0, 64, t, 8);
        t += 0.11;
        delay_ms(100);

    }

}


